// src/utils/mapUtils.ts

import Map from 'ol/Map';
import View from 'ol/View';
import XYZ from 'ol/source/XYZ';
import TileLayer from 'ol/layer/Tile';
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import GeoJSON from 'ol/format/GeoJSON';
import { Style, Fill, Stroke } from 'ol/style';
import Draw from 'ol/interaction/Draw';
import Overlay from 'ol/Overlay';
import Layer from 'ol/layer/Layer';
import { MapBrowserEvent } from 'ol';
import Feature from 'ol/Feature';

// 假设 getCityBoundaryUrl 存在于 '@/api/map'
import { getCityBoundaryUrl } from '@/api/map';

// 定义绘图/边界图层样式
const layerStyle = new Style({
  fill: new Fill({ color: 'rgba(255,0,0,0.5)' }),
  stroke: new Stroke({ color: 'black', width: 2 }),
});

// 定义 MapManager 类来封装所有 OpenLayers 实例和操作
export class MapManager {
  private map: Map | null = null;
  private popup: Overlay | null = null;
  private cityLayer: VectorLayer<VectorSource> | null = null;
  private drawLayer: VectorLayer<VectorSource> | null = null;
  private drawInteraction: Draw | null = null;

  /**
   * 1. 初始化基础地图、弹窗和绘图图层
   * @param mapContainer 地图容器元素
   * @param popupElement 弹窗容器元素
   * @param onFeatureClick 边界点击事件回调，用于更新组件的 popupContent
   */
  public initializeMap(
    mapContainer: HTMLElement,
    popupElement: HTMLElement,
    onFeatureClick: (content: string, position: number[] | undefined) => void
  ): void {
    // 初始化地图
    this.map = new Map({
      target: mapContainer,
      view: new View({
        projection: 'EPSG:4326',
        center: [114.25, 30.59],
        zoom: 4,
      }),
      layers: [
        new TileLayer({
          source: new XYZ({
            url: 'http://wprd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}',
          }),
        }),
      ],
    });

    // 初始化弹窗
    this.popup = new Overlay({
      element: popupElement,
    });
    this.map.addOverlay(this.popup);

    // 初始化绘图图层
    this.drawLayer = new VectorLayer({
      source: new VectorSource(),
      style: layerStyle,
    });
    this.map.addLayer(this.drawLayer);

    // 添加点击事件监听器
    this.map.on('click', (e: MapBrowserEvent<any>) => {
      this.handleMapClick(e, onFeatureClick);
    });
  }

  /**
   * 2. 移除所有已添加的城市边界图层
   */
  private removeAllCityLayers(): void {
    if (!this.map) return;
    const allLayers = this.map.getLayers();
    const targetLayers = allLayers.getArray().filter(
      (layer) => layer.getClassName() === 'city-layer'
    );
    targetLayers.forEach((layer) => this.map!.removeLayer(layer as Layer));
  }

  /**
   * 3. 添加城市边界图层并定位
   * @param adcode 城市adcode编码
   * @param location 城市经纬度数组 [lng, lat]
   */
  public addCityBoundary(adcode: string, location: number[]): void {
    if (!this.map) return;
    
    // 确保在添加新图层前移除旧的边界图层
    this.removeAllCityLayers(); 

    this.cityLayer = new VectorLayer({
      className: 'city-layer',
      source: new VectorSource({
        url: getCityBoundaryUrl(adcode),
        format: new GeoJSON(),
      }),
      style: layerStyle,
    });

    this.map.addLayer(this.cityLayer);
    this.setMapView(location, 8);
  }

  /**
   * 4. 设置地图视角
   * @param center 城市经纬度数组 [lng, lat]
   * @param zoom 缩放级别
   */
  public setMapView(center: number[], zoom: number = 4): void {
    this.map?.getView().animate({
      center: center,
      zoom: zoom,
      duration: 2000,
    });
  }

  /**
   * 5. 切换绘图工具
   * @param type 绘图类型
   */
  public toggleDrawInteraction(type: 'line' | 'circle' | 'polygon' | 'freehand' | 'clear' | ''): void {
    if (!this.map || !this.drawLayer) return;

    // 移除现有交互
    if (this.drawInteraction) {
      this.map.removeInteraction(this.drawInteraction);
      this.drawInteraction = null;
    }
    
    const source = this.drawLayer.getSource()!;

    if (type === 'clear') {
      source.clear();
      return;
    }
    
    if (type) {
      let drawType: 'LineString' | 'Circle' | 'Polygon' = 'LineString';
      let freehand = false;

      switch (type) {
        case 'line':
          drawType = 'LineString';
          break;
        case 'circle':
          drawType = 'Circle';
          break;
        case 'polygon':
          drawType = 'Polygon';
          break;
        case 'freehand':
          drawType = 'LineString';
          freehand = true;
          break;
        default:
          return;
      }
      
      this.drawInteraction = new Draw({ 
        type: drawType, 
        source: source, 
        freehand: freehand 
      });

      this.map.addInteraction(this.drawInteraction);
    }
  }

  /**
   * 6. 注册缩放级别监听器
   */
  public registerZoomListener(): void {
    if (!this.map) return;
    const view = this.map.getView();
    view.on('change:resolution', () => {
      const zoom = view.getZoom();
      if (zoom !== undefined && zoom > 10) {
        this.cityLayer?.setVisible(false);
        this.drawLayer?.setVisible(false);
      } else {
        this.cityLayer?.setVisible(true);
        this.drawLayer?.setVisible(true);
      }
    });
  }

  /**
   * 7. 处理地图点击事件
   */
  private handleMapClick(
    e: MapBrowserEvent<any>,
    onFeatureClick: (content: string, position: number[] | undefined) => void
  ): void {
    if (!this.map || !this.popup) return;

    const feature = this.map.forEachFeatureAtPixel(
      e.pixel,
      (f, l) => {
        if (l instanceof VectorLayer && l.getClassName() === 'city-layer') {
          return f as Feature;
        }
        return undefined;
      }
    ) as Feature | undefined;

    if (feature) {
      const properties = feature.getProperties();
      const center = properties.center;
      const name = properties.name;

      const content = name && center
        ? `
          <p>当前城市是：${name}</p>
          <p>经度：${center[0]}</p>
          <p>纬度：${center[1]}</p>
        `
        : '';
        
      // 通过回调函数更新 Vue 组件的状态
      onFeatureClick(content, center);
      this.popup.setPosition(center || undefined);
    } else {
      // 通过回调函数清除 Vue 组件的状态
      onFeatureClick('', undefined); 
      this.popup.setPosition(undefined);
    }
  }
}